Add chipStar (SPIR-V) support for HIP backends#1942
Add chipStar (SPIR-V) support for HIP backends#1942
Conversation
|
Note: Please use the libCEED PR template, including the LLM usage declaration. Thanks (requirement in CONTRIBUTING.md) |
|
@jeremylt When will the CI run for this PR? |
|
We have to manually trigger any jobs from forks, so just let us know when you want to run CI. I just approved CI running for the current push. |
Detect HIP platform at build time via hipconfig output: - __HIP_PLATFORM_SPIRV__ → HIP_LIB_NAME=CHIP (chipStar) - __HIP_PLATFORM_HCC__/__HIP_PLATFORM_AMD__ → HIP_LIB_NAME=amdhip64 Move ROCM_DIR and HIP_ARCH defaults to the top of the file where other tool-path defaults live. Use HIP_LIB_NAME in the library detection glob and in PKG_LIBS. Remove the subst=,, stripping from HIPCONFIG_CPPFLAGS so flags are passed through unmodified.
When SYCL backends are built, libceed.so must be linked with icpx (SYCLCXX) rather than g++, and -fsycl must appear in CEED_LDFLAGS (before object files) so icpx can merge the SYCL fat binary device sections. Without this, libceed.so lacks NEEDED: libsycl.so.7 and SYCL kernels fail to load at runtime.
|
@jeremylt I've addressed the review feedback in the latest push:
Could you re-trigger CI when convenient? Thanks! |
|
Follow-up: replaced the stderr line filter with |
|
@jeremylt We disabled the HIP backend checks when we removed the AMD card from Noether, right? Did we ever try and get it back going with the NVIDIA card? I'm afraid the CI may not be actually testing the code here (assuming I understand how chip star interacts with the backends). |
Correct - CI is only testing that the build system is correct and that the HIP backend compiles correctly. |
|
Overall this is looking pretty great. I need to do manual testing of the changes since ROCm testing isn't part of CI (as discussed above). Can you post the output of |
zatkins-dev
left a comment
There was a problem hiding this comment.
I think that hijacking the HIP backend for this support is interesting, but creates more brittle and confusing code. I think that this ought to be its own backend, perhaps utilizing the same inner kernels, to clarify the differences with the existing HIP backend
I obviously don't work on the backends that much, so take my opinion with a grain of salt. But the point of chipStar is to just operate straight on HIP code and the changes made, while a bit confusing, are pretty minimal. Perhaps maybe there's some cleaner way to implement the changes. |
I think my main issue is why is this necessary and in what situations. I don't understand it, which means I can't maintain it. |
|
The GPU backends are in a tricky spot with maintainability today, let alone 2 months from now, so I think its a good concern to voice. I agree that the why about not looping over elements is not clear to me either. |
|
@zatkins-dev I wouldn't call this hijacking since chipStar is a full HIP implementation+runtime. The only real change here is the hoisting of These changes are benign but I can run some performance benchmarks on MI50 before and after this refactor and report performance. Having two HIP backends doesn't make sense to me even in the case where there is a performance impact on the AMD side. If I observe a performance degradation on the AMD side, we can discuss how to best set this up. |
|
If the goal is to prevent some threads from not hitting sync points, I would tackle this differently. I have done that before with other kernels. Let me take a look at the code again. |
|
Hijacking may have been a strong word, I meant no offense. I am not concerned about performance, since the macro restores the existing code. I am concerned about how this can be doing the same computation when it removes a loop over elements. I am also confused as to why only the two files that you changed need these changes. As one of the people who will have to maintain this code in the future, I need to know when I should or should not be using these annotations, and I currently have no mental model for that. |
|
I would use the approach in #1950 instead of the macro magic. I think it should do what you're trying to do, but clearer so it can be maintained. I do think that for a big change like this, it is better to first create an issue so design decisions can be discussed first. |
…r gcc chipStar's hipconfig -C outputs --offload=spirv64, -nohipwrapperinc, --hip-path=, and --target= which are clang-only flags. When CC=gcc is used for .c files (or CXX != HIPCC for .cpp files), these flags cause build failures. Add HIPCONFIG_CPPFLAGS_C that filters the clang-only flags and adds an explicit -I$(ROCM_DIR)/include (since -nohipwrapperinc was suppressing the wrapper that would have pulled in hip_runtime.h).
Add a generic --env KEY=VAL CLI option (repeatable) to tests/junit.py
that injects environment variables into the test subprocess environment.
The flag mutates os.environ in the parent before mp.Pool is created, so
worker processes inherit the values via the existing init_process()
copy.
Useful for backend-specific runtime knobs that affect test behavior, for
example silencing chipStar runtime informational/warning lines that
JUnit otherwise classifies as test failures:
make junit BACKENDS='/gpu/hip/ref ...' \
JUNIT_ARGS='--env CHIP_LOGLEVEL=crit'
No changes to tests/junit_common.py.
chipStar HIP headers do not transitively include <cstring>, causing build failures for the four pre-existing strcmp() calls in this file (resource_root comparisons). AMD ROCm headers include it transitively, so this is a no-op on non-chipStar builds.
|
After discussion with @jeremylt, I've pulled all kernel changes out of this PR. @jeremylt's PR #1950 handles the syncthreads fix with a cleaner loop-padding approach that works across all platforms without preprocessor guards. This PR now focuses only on the build-system and test-infrastructure changes needed for chipStar support. What's in this PR now
Answers to inline review comments@zatkins-dev on @zatkins-dev on @zatkins-dev on Note on PR #1950I verified the loop-padding approach empirically on chipStar and found a formula bug: chipStar test invocation (for reference)make junit BACKENDS='/gpu/hip/shared /gpu/hip/gen /gpu/hip/ref' JUNIT_ARGS='--env CHIP_LOGLEVEL=crit'Test resultsWith the loop-padding approach (corrected formula equivalent to what I posted on #1950), the following pass on chipStar (Intel Arc A770, Level Zero):
Full |
|
It looks like you heavily use Claude or something similar in your workflow - don't forget to update the LLM usage the disclosure so we know how you do so. Note - you are replying to human generated review comments with machine generated messages. I think it's worth keeping in mind that is a potential frustration point |
| from junit_common import * | ||
|
|
||
|
|
||
| def parse_env_assignment(arg: str) -> Tuple[str, str]: |
There was a problem hiding this comment.
@zatkins-dev is this how you want this to work and should this be in the core? JUNIT has become mainly yours, so I don't want to make changes without your OK.
There was a problem hiding this comment.
I think this is mostly reasonable -- it's a fine feature to support in the libCEED junit suite if we need it.
I do think that if our tests are triggering chipstar warnings, then either
- The warnings are indicating an actual issue, in which case we should fix whatever is causing the warning
- The warning is not a real issue, in which case chipStar should not be emitting it by default.
It is pretty normal to expect libraries to be quiet/have a way to programmatically suppress output rather than only relying on environment variables, as environment variables are not portable and are subject to annoying requirements as in this case.
Just to be clear, does running this not work? We use environment variables like PETSC_OPTIONS in this way for the test suite, so it would be odd if that didn't work for chipstar.
export CHIP_LOGLEVEL=crit
make prove -jIf so, we should just do that instead if/when we add it to CI, as that would be easier.
I also think that we could (and perhaps should) set the environment within libCEED using the C standard library so that users are not forced to also set this environment variable to suppress output in their test suites.
TLDR, we should just set the environment before calling make junit, and if that doesn't work can chipStar please add a way to set this log level via a library function or something and/or can we fix whatever is causing the warnings?
| subsearch ?= .* | ||
| JUNIT_BATCH ?= '' | ||
| # Extra arguments forwarded to tests/junit.py (e.g. --env CHIP_LOGLEVEL=crit) | ||
| JUNIT_ARGS ?= |
There was a problem hiding this comment.
Ideally, we should automatically suppress the Chipstar warnings when we build with Chipstar so the test suite passes - so JUNIT_ARGS should be set appropriately by default if Chipstar is enabled
| HIP_LIB_NAME = CHIP | ||
| else ifneq (,$(findstring __HIP_PLATFORM_HCC__,$(HIP_CONFIG_RES))) |
There was a problem hiding this comment.
| HIP_LIB_NAME = CHIP | |
| else ifneq (,$(findstring __HIP_PLATFORM_HCC__,$(HIP_CONFIG_RES))) | |
| HIP_LIB_NAME = CHIP | |
| JUNIT_ARGS += --env CHIP_LOGLEVEL=crit | |
| else ifneq (,$(findstring __HIP_PLATFORM_HCC__,$(HIP_CONFIG_RES))) |
I think this will work?
Purpose:
Add support for chipStar, enabling libCEED HIP backends (
/gpu/hip/ref,/gpu/hip/shared,/gpu/hip/gen) to run on any OpenCL or Level Zero GPU (Intel, etc.) via SPIR-V.Changes
__HIP_PLATFORM_SPIRV__), handle dynamic lib name (libCHIP.sovslibamdhip64.so), filter clang-only flags fromHIPCONFIG_CPPFLAGSwhen using gcc asCC, useSYCLCXXas linker when SYCL backend is also enabled#ifdef __HIP_PLATFORM_SPIRV__): chipStar SPIR-V target requires all threads in a workgroup to reach__syncthreads()barriers. Kernel element loops are refactored to a single-assignment + guard pattern on chipStar, while preserving the original for-loop structure on AMD ROCm/NVIDIAhip-ref-basis-nontensor.h: 5 kernel functionship-shared-basis-tensor.h: 13 kernel functionsceed-hip-gen-operator-build.cpp: code-generator emits conditional kernel sourceerrors='replace'for binary data in subprocess outputBenchmarks: HIP (chipStar) vs SYCL (oneAPI) on Intel Arc A770
chipStar main + hiprtc output caching. oneAPI 2024.2.2 + Level Zero. 5M DOFs, polynomial degree p=4, warm JIT cache.
Testing was done with SYCL Caching PR #1943 otherwise chipStar outperforms SYCL much more due to JIT costs.
ex1-volume (mass operator)
ex2-surface (surface integral)
chipStar HIP is 15-52% faster than native SYCL across all backends.
LLM/GenAI Disclosure:
Claude Code was used to rebase on latest main (bulk of this work was done in 2024/2025), write the
#ifdef __HIP_PLATFORM_SPIRV__preprocessor guards across HIP kernel files and the code-generator, and to draft this PR description.By submitting this PR, the author certifies to its contents as described by the Developer's Certificate of Origin.
Please follow the Contributing Guidelines for all PRs.